package org.javaboy.authentication_manager.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

import java.util.Arrays;

@Configuration
public class SecurityConfig {

    //    @Bean
    UserDetailsService us() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("zhangsan").password("{noop}123").build());
        return manager;
    }
    UserDetailsService us2() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("lisi").password("{noop}123").build());
        return manager;
    }

    /**
     * 配置 AuthenticationManager
     *
     * @return
     */
    AuthenticationManager authenticationManager() {
        //AuthenticationProvider 是专门做认证数据校验的
        //如果登录用户来自数据库，那么就使用 DaoAuthenticationProvider 进行校验
        //DaoAuthenticationProvider 的作用，就是找出来用户名，然后根据用户名去数据库中查询，找到用户，然后去判断用户的状态、密码等等是否 OK
        DaoAuthenticationProvider providers = new DaoAuthenticationProvider();
        providers.setUserDetailsService(us());
        ProviderManager manager = new ProviderManager(Arrays.asList(providers), parentAuthenticationManager());
        return manager;
    }

    private AuthenticationManager parentAuthenticationManager() {
        //AuthenticationProvider 是专门做认证数据校验的
        //如果登录用户来自数据库，那么就使用 DaoAuthenticationProvider 进行校验
        DaoAuthenticationProvider providers = new DaoAuthenticationProvider();
        providers.setUserDetailsService(us2());
        ProviderManager manager = new ProviderManager(providers);
        return manager;
    }

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(a -> a.anyRequest().authenticated())
                .authenticationManager(authenticationManager())
                .formLogin(f -> f.permitAll()).csrf(c -> c.disable());
        return http.build();
    }
}
